#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import json
import stat
import platform
import locale
import subprocess
import shlex

from common.common_models import ActionResult
from common.const import ParamConstant
from adds.comm.log import log


def check_path_legal(file_path):
    real_dir_path = os.path.realpath(file_path)
    system_drive_up = os.getenv("SystemDrive").upper()
    system_drive_down = system_drive_up.lower()
    if real_dir_path.startswith(system_drive_up) or \
            real_dir_path.startswith(system_drive_down):
        if os.path.dirname(real_dir_path) != os.path.realpath(ParamConstant.RESULT_PATH) \
                and os.path.dirname(real_dir_path) != os.path.realpath(ParamConstant.PARAM_FILE_PATH):
            log.warn("File path not support to write")
            raise Exception("File path not support to write")


def output_execution_result_ex(file_path, payload):
    # 先将文件清空再写
    check_path_legal(file_path)
    json_str = json.dumps(payload)
    flags = os.O_WRONLY | os.O_CREAT
    modes = stat.S_IWUSR | stat.S_IRUSR | stat.S_IXUSR
    with os.fdopen(os.open(file_path, flags, modes), 'w') as out_file:
        out_file.truncate(0)
        out_file.write(json_str)


def output_action_result(pid, code, body_err, message, err_params: list = None):
    """
    将actionResult写入到结果文件,供框架读取
    :return:
    """
    json_result = ActionResult(code=code, bodyErr=body_err, message=message, bodyErrParams=err_params)
    file_path = os.path.join(ParamConstant.RESULT_PATH, f"result{pid}")
    log.info(f"Write file.path:{file_path} action code: {code}, body_err: {body_err}, message: {message}")
    output_execution_result_ex(file_path, json_result.dict(by_alias=True))


def execute_cmd(cmd, encoding=None, timeout=None, cmd_array_flag=False):
    """
    执行不包含管道符的命令
    :param cmd: 命令
    :param encoding: 使用自定义编码
    :param timeout: 执行命令超时
    :param cmd_array_flag:命令是否直接为数组格式
    :return: (字符串格式, 标准输出, 标准错误)
    """
    if not encoding:
        encoding = locale.getdefaultlocale()[1]
    if not cmd_array_flag:
        cmd = shlex.split(cmd)
    process = subprocess.Popen(cmd, stdin=None, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, encoding=encoding, errors='ignore')
    try:
        std_out, std_err = process.communicate(timeout=timeout)
    except TimeoutError as err:
        process.kill()
        ret_code = 1
        std_out = ""
        std_err = str(err)
    else:
        ret_code = process.returncode
    return str(ret_code), std_out, std_err
